/** 查询表格逻辑封装 */
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {PAGE, PAGINATION_OPTIONS} from '../../constants';
import {conventSorter} from '../../utils';

export default class QueryTableWrapper extends Component {
    static propTypes = {
        getData: PropTypes.func.isRequired, // 需要返回 Promise
        children: PropTypes.func,
        getDefaultFormData: PropTypes.func,
    }

    static defaultProps = {
        getDefaultFormData: () => ({})
    }

    state = {
        formData: this.props.getDefaultFormData(),
        tableCondition: {
            pageIndex: PAGE.index,
            pageSize: PAGE.smallSize
        },
        tableData: {
            content: []
        },
        message: '',
        isFetching: false, // 查询面板触发
        loading: false // 表格触发
    }

    setFormData = object => {
        this.setState(state => ({
            formData: {
                ...state.formData,
                ...object
            }
        }));
        return Promise.resolve();
    }

    clearFormData = () => {
        this.setState({
            formData: this.props.getDefaultFormData()
        });
    }

    setTableCondition = data => {
        this.setState(state => ({
            tableCondition: data,
            // 此时需要同步修改 formData
            formData: {
                ...state.formData,
                ...data
            }
        }));
    }

    setTableData = data => {
        this.setState({
            tableData: data
        });
    }

    handleFilterChange = (value, name) => {
        this.setFormData({[name]: value});
    }

    handleFilterPressEnter = (value, name) => {
        this.setFormData({[name]: value}).then(() => {
            this.handleFormQuery();
        });
    }
    
    getData = condition => this.props.getData(condition).then(res => {
        if(res.ok) {
            this.setTableCondition(condition);
            this.setTableData(res.data);
        }
        return res;
    })

    handleTableChange = (pagination, filters, sorter) => {
        const oldCondition = this.state.tableCondition;
        const pageIndex = pagination.current - 1 === oldCondition.pageIndex
            ? PAGE.index : pagination.current - 1;
        const sortOptions = conventSorter(sorter);
        const condition = {
            ...oldCondition,
            ...sortOptions,
            pageSize: pagination.pageSize,
            pageIndex
        };
        this.setState({
            loading: true
        });
        this.getData(condition).then(res => {
            this.setState({
                message: res.ok ? '' : res.message,
                loading: false
            });
        });
    };

    handleFormQuery = () => {
        this.setState({
            isFetching: true
        });
        const condition = {
            ...this.state.formData,
            pageIndex: PAGE.index
        };
        this.getData(condition).then(res => {
            this.setState({
                message: res.ok ? '' : res.message,
                isFetching: false
            });
        });
    }

    toggleLoading = bool => {
        if(bool === true || bool === false)
            this.setState({
                loading: bool
            });
        else
            this.setState(state => ({
                loading: !state.loading
            }));
    }

    render() {
        const {children: Children} = this.props;
        const pagination = {
            total: this.state.tableData.totalElements,
            current: this.state.tableCondition.pageIndex + 1,
            pageSize: this.state.tableCondition.pageSize,
            ...PAGINATION_OPTIONS
        };

        return (
            <Children
                handleFormQuery={this.handleFormQuery}
                handleTableChange={this.handleTableChange}
                handleFilterPressEnter={this.handleFilterPressEnter}
                handleFilterChange={this.handleFilterChange}
                clearFormData={this.clearFormData}
                toggleLoading={this.toggleLoading}
                formData={this.state.formData}
                tableData={this.state.tableData}
                pagination={pagination}
                isFetching={this.state.isFetching}
                message={this.state.message}
                loading={this.state.loading}/>
        );
    }
}

